package com.iring.service.pay.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.stereotype.Service;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.request.AlipayTradeCloseRequest;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradeCloseResponse;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.iring.domain.config.PayConfig;
import com.iring.domain.config.prop.AliPayProperties;
import com.iring.domain.config.prop.PayProperties;
import com.iring.domain.pay.AliRequstInfo;
import com.iring.domain.pay.check.AlipayCheck;
import com.iring.domain.pay.info.AliPayInfo;
import com.iring.domain.pay.res.AliPayRes;
import com.iring.exception.ParamInvalidException;
import com.iring.exception.config.ErrorEnum;
import com.iring.service.pay.PayService;
import com.iring.util.common.CommonUtil;
import com.iring.util.common.JacksonUtil;

/**
 * @author wanggan
 */
@Service("alipay")
@ConditionalOnBean(AliPayProperties.class)
public class AliPayServiceImpl implements PayService<AliPayInfo,AliPayRes,AlipayCheck> {
    private static final Logger logger = LoggerFactory.getLogger(AliPayServiceImpl.class);

    @Autowired
    PayProperties payProperties;

    @Autowired
    AliPayProperties aliPayProperties;

    @Autowired
    CommonUtil commonUtil;

    @Autowired
    AlipayClient alipayClient;

    @Override
    public AlipayCheck cancelPay(AliPayInfo payInfo) {
        AlipayTradeCloseRequest tradeCloseRequest = new AlipayTradeCloseRequest();
        tradeCloseRequest.setBizContent("{\"out_trade_no\":\""+payInfo.getOut_trade_no()+"\"}");
        AlipayTradeCloseResponse response = null;
        try {
            response = alipayClient.execute(tradeCloseRequest);
        } catch (AlipayApiException e) {
            logger.info("close alipay failed={}",e);
        }
        AlipayCheck alipayCheck = new AlipayCheck();

        if(response.isSuccess()){
            alipayCheck.setTradeNo(response.getTradeNo());
            alipayCheck.setOrderId(response.getOutTradeNo());
            alipayCheck.setPayResult(true);
            logger.info("close order success,orderid={},tradeno={}",response.getOutTradeNo(),response.getTradeNo());
        } else {
            alipayCheck.setPayResult(false);
        }
        return alipayCheck;
    }
    @Override
    public AliPayRes createPay(AliPayInfo aliPayInfo) {

        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();//创建API对应的request
        String returnUrl = aliPayProperties.getReturnUrl();
        String notifyUrl = aliPayProperties.getNotifyUrl();

        alipayRequest.setReturnUrl(returnUrl);
        alipayRequest.setNotifyUrl(notifyUrl);//在公共参数中设置回跳和通知地址

        AliRequstInfo aliRequstInfo = new AliRequstInfo();
        String orderid = aliPayInfo.getOut_trade_no();
        aliRequstInfo.setOut_trade_no(orderid);
        aliRequstInfo.setProduct_code(aliPayProperties.getProductCode());
        aliRequstInfo.setTotal_amount(Double.valueOf(aliPayInfo.getTotal_amount()));

        String orderDescribe = payProperties.getDescrible();
        aliRequstInfo.setSubject(orderDescribe);
        aliRequstInfo.setBody(orderDescribe.toLowerCase());
//        aliRequstInfo.setTimeout_express(aliPayProperties.getOrderTimeout());
        alipayRequest.setBizContent(JacksonUtil.toJSon(aliRequstInfo));//填充业务参数
//        alipayRequest.setBizContent("{\"out_trade_no\":\"20171230121811Xuh4T7nNyp\",\"product_code\":\"FAST_INSTANT_TRADE_PAY\",\"total_amount\":\"10.00\",\"subject\":\"ZYCOO TOP-UP\",\"body\":\"zycoo top-up\",\"goods_type\":\"0\",\"timeout_express\":\"1d\"}");//填充业务参数
        AlipayTradePagePayResponse alipayTradePagePayResponse = null;
        //此时并不会返回交易号，需要等到用户进行支付，才能进行获取订单的tradeNo和支付人的信息
        try {
            alipayTradePagePayResponse = alipayClient.pageExecute(alipayRequest);
        } catch (AlipayApiException e) {
            try {
                alipayTradePagePayResponse = alipayClient.pageExecute(alipayRequest);
            } catch (AlipayApiException e1) {
                logger.info("create alipay exception = {}",e);
                throw new ParamInvalidException(ErrorEnum.CREATE_ORDER_FAILED);
            }
        }

        AliPayRes aliPayRes = new AliPayRes();

        if(alipayTradePagePayResponse instanceof AlipayTradePagePayResponse ){
            if(alipayTradePagePayResponse.isSuccess()) {
                aliPayRes.setOrderHref(alipayTradePagePayResponse.getBody());
                aliPayRes.setTradeNo(alipayTradePagePayResponse.getTradeNo());
                aliPayRes.setState(PayConfig.WAIT_BUYER_PAY);
            }else{
                String code = alipayTradePagePayResponse.getCode();
                String msg = alipayTradePagePayResponse.getMsg();
                throw new ParamInvalidException(code,msg);
            }
        }else{
            throw new ParamInvalidException(ErrorEnum.CREATE_ORDER_FAILED);
        }
        aliPayRes.setOrderid(orderid);
        return aliPayRes;
    }

    @Override
    public AlipayCheck checkPay(AlipayCheck checkPayInfo) {

        String outTradeNo = checkPayInfo.getOrderId();
        AlipayTradeQueryResponse response = queryOrder(outTradeNo);

        AlipayCheck alipayCheck = new AlipayCheck();
        if(null == response){
            alipayCheck.setPayResult(false);
            return alipayCheck;
        }
        if(response.isSuccess()){
            alipayCheck.setPayResult(true);
            alipayCheck.setPayStatus(response.getTradeStatus());
            alipayCheck.setPayerId(response.getBuyerUserId());
            alipayCheck.setTradeNo(response.getTradeNo());
        }else {
            alipayCheck.setPayResult(false);
        }
        return alipayCheck;
    }


    /**
     * 查询订单信息
     * @param outTradeNo
     *          订单号
     * @return  订单详情
     */
    private  AlipayTradeQueryResponse queryOrder(String outTradeNo){
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        request.setBizContent("{\"out_trade_no\":\""+outTradeNo+"\"}");
        AlipayTradeQueryResponse response = null;
        try {
            response = alipayClient.execute(request);
        } catch (AlipayApiException e) {
            logger.info("query order exception={}",e);
        }
        return response;
    }
}
